﻿#include "context.h"

#include <iostream>

std::shared_ptr<Context> Context::create()
{
    return std::make_shared<Context>();
}

Context::Context()
{
    createInstance();
    selectPhyiscalDevice();
    queryQueueFamilyIndices();
    createDevice();
    getQueues();
}

Context::~Context()
{
    m_device.destroy();
    m_instance.destroy();
}

void Context::createInstance()
{
    // auto layers = vk::enumerateInstanceLayerProperties();
    // for (auto& layer : layers)
    // {
    //     std::cout << layer.layerName << std::endl;
    // }
    std::vector<const char*> layers = {"VK_LAYER_KHRONOS_validation"};

    vk::ApplicationInfo appInfo;
    appInfo.setApiVersion(VK_API_VERSION_1_3)\
            .setPEngineName("No Engine");

    vk::InstanceCreateInfo createInfo;
    createInfo.setPApplicationInfo(&appInfo)\
              .setPEnabledLayerNames(layers);

    m_instance = vk::createInstance(createInfo);
}

void Context::selectPhyiscalDevice()
{
    auto devices = m_instance.enumeratePhysicalDevices();
    // for (auto& device : devices)
    // {
    //     std::cout << device.getProperties().deviceName << std::endl;
    // }

    m_phyDevice = devices[0];
}

void Context::createDevice()
{
    auto layers = m_phyDevice.enumerateDeviceLayerProperties();
    for (auto& layer : layers)
    {
        std::cout << layer.layerName << std::endl;
    }

    vk::DeviceQueueCreateInfo queueCreateInfo;
    float priorities = 1.0;  //优先级 最高为1 最低为0
    queueCreateInfo.setPQueuePriorities(&priorities)\
                   .setQueueCount(1)\
                   .setQueueFamilyIndex(m_queuefamliyIndices.graphicsQueue.value());

    vk::DeviceCreateInfo createInfo;
    createInfo.setQueueCreateInfos(queueCreateInfo);  //command queue

    m_device = m_phyDevice.createDevice(createInfo);
}

void Context:: queryQueueFamilyIndices()  //查询物理设备队列支持的功能
{
    auto properties = m_phyDevice.getQueueFamilyProperties();
    for (size_t i = 0; i < properties.size(); i++)
    {
        auto& property = properties[i];
        //property.queueCount; //最多可以创建队列的个数
        if (property.queueFlags & vk::QueueFlagBits::eGraphics)
        {
            m_queuefamliyIndices.graphicsQueue = i;
            break;
        }
    }
}

void Context::getQueues()
{
    m_gpaphcisQueue = m_device.getQueue(m_queuefamliyIndices.graphicsQueue.value(), 0);
}